package ar.edu.itba.pod.Legajo47342.communication;

import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import ar.edu.itba.pod.Legajo47342.Node;
import ar.edu.itba.pod.simul.communication.ClusterAdministration;
import ar.edu.itba.pod.simul.communication.ClusterCommunication;
import ar.edu.itba.pod.simul.communication.ConnectionManager;
import ar.edu.itba.pod.simul.communication.ReferenceName;
import ar.edu.itba.pod.simul.communication.SimulationCommunication;
import ar.edu.itba.pod.simul.communication.ThreePhaseCommit;
import ar.edu.itba.pod.simul.communication.Transactionable;

public class ConnectionManagerImpl implements ConnectionManager, ReferenceName {
	private ClusterAdministration admin;
	private ClusterCommunication comm;
	private Transactionable trans;
	private SimulationCommunication simul;
	private ThreePhaseCommit tpcomm;
	private Node node;
	
	public ConnectionManagerImpl(Node node) throws RemoteException{
		super();
		
		this.admin = new ClusterAdministrationImpl(node);
		this.comm = new ClusterCommunicationImpl(node);
		this.trans = new TransactionableImpl(node);
		this.simul = new SimulationCommunicationImpl(node);
		this.tpcomm = new ThreePhaseCommitImpl(node);
		
		this.node = node;
		
		ConnectionManager stub =
		    (ConnectionManager) UnicastRemoteObject.exportObject(this, 0);
	
		//Registry registry = LocateRegistry.getRegistry();
		Registry registry = LocateRegistry.createRegistry(getClusterPort());
		try {
			registry.bind(CONNECTION_MANAGER_NAME, stub);
		} catch (AlreadyBoundException e) {
			e.printStackTrace();
		}
		
	}

	@Override
	public int getClusterPort() throws RemoteException {
		return 1099;
	}

	@Override
	public ConnectionManager getConnectionManager(String nodeId)
			throws RemoteException {
		
		 Registry registry = LocateRegistry.getRegistry(nodeId);
		 //System.out.println("en get CONMANAGER "+nodeId);
         try {
			ConnectionManager manager = (ConnectionManager) registry.lookup(CONNECTION_MANAGER_NAME);
			return manager;
		} catch (NotBoundException e) {
			e.printStackTrace();
		}
		
		throw new RemoteException();
	}

	@Override
	public ClusterCommunication getGroupCommunication() throws RemoteException {
		return comm;
	}

	@Override
	public ClusterAdministration getClusterAdmimnistration()
			throws RemoteException {
		return admin;
	}

	@Override
	public Transactionable getNodeCommunication() throws RemoteException {
		return trans;
	}

	@Override
	public SimulationCommunication getSimulationCommunication()
			throws RemoteException {
		return simul;
	}

	@Override
	public ThreePhaseCommit getThreePhaseCommit() throws RemoteException {
		return tpcomm;
	}

	public Node getNode() {
		return node;
	}

}
